﻿using System;
using Viettel.VOFFICE.DAO.DAL.Repository;
using Viettel.VOFFICE.DAO.Models;

namespace Viettel.VOFFICE.DAO.DAL
{
    /// <summary>
    /// Quản lý các repository và context kết nối đến csdl
    /// Khởi tạo transaction
    /// </summary>
    public class UnitOfWork : IUnitOfWork
    {
        public UnitOfWork()
        {
            context = new VOFFICEContext();
        }
        #region TRANSACTION
        /// <summary>
        /// Lấy thông tin về transaction hiện tai
        /// </summary>
        /// <returns></returns>
        public ITransaction BeginTransaction()
        {
            return new Transaction(this);
        }

        /// <summary>
        /// Kết thúc trangsactions
        /// </summary>
        /// <param name="transaction"></param>
        public void EndTransaction(ITransaction transaction)
        {
            if (transaction != null)
            {
                (transaction as IDisposable).Dispose();
                transaction = null;
            }
        }
        #endregion TRANSACTION

        #region CONTEXT
        private VOFFICEContext context;
        ///
        ///TODO: Thêm context kết nối đến csdl ở đây
        ///TODO: Thêm hàm hởi tạo unitofwork => khởi tạo context
        ///
        public VOFFICEContext Context
        {
            get
            {
                if (this.context == null)
                {
                    throw new Exception("Could not access DB::errors");
                }
                return this.context;
            }
        }
        #endregion

        #region REPOSITORY
        /// <summary>
        /// Role Repository
        /// </summary>
        private RoleRepository _repository;
        public RoleRepository RoleRepository
        {
            get { return _repository ?? (_repository = new RoleRepository(context)); }
        }
        /// <summary>
        /// User Repository
        /// </summary>
        private UserRepository _userRepository;
        public UserRepository UserRepository
        {
            get { return _userRepository ?? (_userRepository = new UserRepository(context)); }
        }

        /// <summary>
        /// Office Partner Repository
        /// </summary>
        private OfficePartnerRepository _officePartnerRepository;
        public OfficePartnerRepository OfficePartnerRepository
        {
            get { return _officePartnerRepository ?? (_officePartnerRepository = new OfficePartnerRepository(context)); }
        }

        /// <summary>
        /// Flow Repositoty
        /// </summary>
        private FlowRepository _flowRepository;
        public FlowRepository FlowRepository
        {
            get { return _flowRepository ?? (_flowRepository = new FlowRepository(context)); }
        }

        /// <summary>
        /// Node Repository
        /// </summary>
        private NodeRepository _nodeRepository;
        public NodeRepository NodeRepository
        {
            get { return _nodeRepository ?? (_nodeRepository = new NodeRepository(context)); }
        }

        /// <summary>
        /// Book Repository
        /// </summary>
        private BookRepository _bookRepository;
        public BookRepository BookRepository
        {
            get { return _bookRepository ?? (_bookRepository = new BookRepository(context)); }
        }

        /// <summary>
        /// Attachment Repository
        /// </summary>
        private AttachmentRepository _attachmentRepository;
        public AttachmentRepository AttachmentRepository
        {
            get { return _attachmentRepository ?? (_attachmentRepository = new AttachmentRepository(context)); }
        }

        /// <summary>
        /// Comment Repository
        /// </summary>
        private CommentRepository _commentRepository;
        public CommentRepository CommentRepository
        {
            get { return _commentRepository ?? (_commentRepository = new CommentRepository(context)); }
        }

        /// <summary>
        /// Document Repository
        /// </summary>
        private DocumentBookRepository _documentBookRepository;
        public DocumentBookRepository DocumentBookRepository
        {
            get { return _documentBookRepository ?? (_documentBookRepository = new DocumentBookRepository(context)); }
        }

        /// <summary>
        /// Document Progress Repository
        /// </summary>
        private DocumentProgressRepository _documentProgressRepository;
        public DocumentProgressRepository DocumentProgressRepository
        {
            get { return _documentProgressRepository ?? (_documentProgressRepository = new DocumentProgressRepository(context)); }
        }

        /// <summary>
        /// Document Property Repository
        /// </summary>
        private DocumentPropertyRepository _documentPropertyRepository;
        public DocumentPropertyRepository DocumentPropertyRepository
        {
            get { return _documentPropertyRepository ?? (_documentPropertyRepository = new DocumentPropertyRepository(context)); }
        }

        /// <summary>
        /// Document Publish Repository
        /// </summary>
        private DocumentOutboxRepository _documentPublishRepository;
        public DocumentOutboxRepository DocumentPublishRepository
        {
            get { return _documentPublishRepository ?? (_documentPublishRepository = new DocumentOutboxRepository(context)); }
        }

        /// <summary>
        /// Document Receive Repository
        /// </summary>
        private DocumentInboxRepository _documentReceiveRepository;
        public DocumentInboxRepository DocumentReceiveRepository
        {
            get { return _documentReceiveRepository ?? (_documentReceiveRepository = new DocumentInboxRepository(context)); }
        }

        /// <summary>
        /// Document Type Repository
        /// </summary>
        private DocumentTypeRepository _documentTypeRepository;
        public DocumentTypeRepository DocumentTypeRepository
        {
            get { return _documentTypeRepository ?? (_documentTypeRepository = new DocumentTypeRepository(context)); }
        }

        /// <summary>
        /// Library Repository
        /// </summary>
        private LibraryRepository _libraryRepository;
        public LibraryRepository LibraryRepository
        {
            get { return _libraryRepository ?? (_libraryRepository = new LibraryRepository(context)); }
        }

        /// <summary>
        /// Meta Data Repository
        /// </summary>
        private MetaDataRepository _metaDataRepository;
        public MetaDataRepository MetaDataRepository
        {
            get { return _metaDataRepository ?? (_metaDataRepository = new MetaDataRepository(context)); }
        }

        /// <summary>
        /// Node Relation Repository
        /// </summary>
        private NodeRelationRepository _nodeRelationRepository;
        public NodeRelationRepository NodeRelationRepository
        {
            get { return _nodeRelationRepository ?? (_nodeRelationRepository = new NodeRelationRepository(context)); }
        }

        /// <summary>
        /// Node User Repository
        /// </summary>
        private NodeUserRepository _nodeUserRepository;
        public NodeUserRepository NodeUserRepository
        {
            get { return _nodeUserRepository ?? (_nodeUserRepository = new NodeUserRepository(context)); }
        }

        /// <summary>
        /// Notification Repository
        /// </summary>
        private NotificationRepository _notificationRepository;
        public NotificationRepository NotificationRepository
        {
            get { return _notificationRepository ?? (_notificationRepository = new NotificationRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private SubmissionRepository _submissionRepository;
        public SubmissionRepository SubmissionRepository
        {
            get { return _submissionRepository ?? (_submissionRepository = new SubmissionRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private TodoRepository _todoRepository;
        public TodoRepository TodoRepository
        {
            get { return _todoRepository ?? (_todoRepository = new TodoRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private TraceFlowRepository _traceFlowRepository;
        public TraceFlowRepository TraceFlowRepository
        {
            get { return _traceFlowRepository ?? (_traceFlowRepository = new TraceFlowRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private DepartmentRepository _deparmentRepository;
        public DepartmentRepository DeparmentRepository
        {
            get { return _deparmentRepository ?? (_deparmentRepository = new DepartmentRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private ActionCollectionRepository _actionCollectionRepository;
        public ActionCollectionRepository ActionCollectionRepository
        {
            get { return _actionCollectionRepository ?? (_actionCollectionRepository = new ActionCollectionRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private ControllerCollectionRepository _controllerCollectionRepository;
        public ControllerCollectionRepository ControllerCollectionRepository
        {
            get { return _controllerCollectionRepository ?? (_controllerCollectionRepository = new ControllerCollectionRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private PositionRepository _positionRepository;
        public PositionRepository PositionRepository
        {
            get { return _positionRepository ?? (_positionRepository = new PositionRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private RoleControllerActionRepository _roleControllerActionRepository;
        public RoleControllerActionRepository RoleControllerActionRepository
        {
            get { return _roleControllerActionRepository ?? (_roleControllerActionRepository = new RoleControllerActionRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private SystemMenuRepository _systemMenuRepository;
        public SystemMenuRepository SystemMenuRepository
        {
            get { return _systemMenuRepository ?? (_systemMenuRepository = new SystemMenuRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private UserControllerActionRepository _userControllerActionRepository;
        public UserControllerActionRepository UserControllerActionRepository
        {
            get { return _userControllerActionRepository ?? (_userControllerActionRepository = new UserControllerActionRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private UsersInDeparmentRepository _usersInDeparmentRepository;
        public UsersInDeparmentRepository UsersInDeparmentRepository
        {
            get { return _usersInDeparmentRepository ?? (_usersInDeparmentRepository = new UsersInDeparmentRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private SystemFunctionRepository _systemFunctionRepository;
        public SystemFunctionRepository SystemFunctionRepository
        {
            get { return _systemFunctionRepository ?? (_systemFunctionRepository = new SystemFunctionRepository(context)); }
        }

        /// <summary>
        /// 
        /// </summary>
        private DocumentInboxRepository _documentInboxRepository;
        public DocumentInboxRepository DocumentInboxRepository
        {
            get { return _documentInboxRepository ?? (_documentInboxRepository = new DocumentInboxRepository(context)); }
        }

        private DocumentOutboxRepository _documentOutboxRepository;
        public DocumentOutboxRepository DocumentOutboxRepository
        {
            get { return _documentOutboxRepository ?? (_documentOutboxRepository = new DocumentOutboxRepository(context)); }
        }
        #endregion

        #region SAVE AND DISPOSE DATA

        /// <summary>
        /// Lưu dữ liệu xuống server
        /// </summary>
        public void Save()
        {
            context.SaveChanges();
        }

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }
            }
            this.disposed = true;
        }

        /// <summary>
        /// Lưu vào giải phóng kết nối
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion SAVE AND DISPOSE DATA
    }
}
